Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

229
Views
Cómo hacer una copia de la colección de hibernación con cascade="all,delete-orphan"

Estoy tratando de hacer una copia de una entidad de hibernación A como esta:

 A a = (A) session.get(A.class, id); session.evict(a); a.setId(null); session.save(a);

Sin embargo, esto no funciona y obtengo la siguiente experiencia:

 org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": com.test.AB

Es seguro asumir que este error ocurre porque tengo una colección de entidades B definidas en la entidad A:

 <list name="B" table="B" lazy="false" cascade="all,delete-orphan"> <key column="A_ID" not-null="true"/> <index column="X"/> <one-to-many class="com.test.B"/> </list>

¿Cómo es posible hacer una copia de la entidad A, incluida su colección de entidades B sin que Hibernate esté descontento con eso?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Si desea copiar una entidad existente, modificarla y guardarla como una nueva entidad, debe realizar una copia profunda de ese objeto. Puede hacer una copia profunda de un objeto serializando y luego deserializando ese objeto.

 public Object deepCopy(Object input) { Object output = null; try { // Writes the object ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(input); // Reads the object ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); output = objectInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); } return output; }
over 4 years ago · Santiago Trujillo Report

0

Tuve el mismo problema anteriormente en mi proyecto.

Para mí funciona, establecer la ID de las entradas de la lista en nulo.

 // make copy a of aOriginal by using serialisation clone a.setId(null); for (B b : a.getBs()) { b.setId(null); } session.save(a);

Para el clon en sí, utilicé el clon de Apache SerializationUtils .

La razón es que hibernate intenta "reutilizar" las entradas de la lista ya persistentes para la entidad "copiada". Pero estas entradas de lista ya persistentes están vinculadas a una entidad original. Entonces intenta "cambiar" la lista en sí misma en la entidad, porque la entidad cambió. Pero no puede cambiar la lista si está anotada con "eliminar huérfanos" (solo puede modificar las entradas de la lista, pero no la lista en sí). Así que se lanza la excepción.

Si configuro los ID de entrada de lista en nulo, también se insertarán newley. Y la jerarquía de objetos (en lugar de solo la entidad principal) se duplica. Entonces la excepción ya no se lanza.

over 4 years ago · Santiago Trujillo Report

0

No hay una forma automática de copiar objetos como ese. En general, el objeto copiado podría estar asociado con otros objetos que están más asociados con otros objetos, etc., por lo que podría terminar copiando una gran parte de la base de datos. Cualquier herramienta que utilice para copiar debe saber en qué parte del gráfico de objetos debe dejar de copiar, qué no copiar (en términos de entidades de Hibernate, son ids, columnas de versión y similares), etc.

Sin embargo, puede utilizar marcos como Dozer para evitar la mayor parte del código repetitivo que necesitaría escribir manualmente.

Con respecto al problema de la reasignación de la colección, no puede tener la misma colección de instancias B asignadas a dos A diferentes, ya que lógicamente sería una asociación many-to-many . También es algo de lo que debería encargarse manualmente, ya que es específico para el caso de uso de su negocio.

Además, asegúrese de no reutilizar los mismos proxies de colección de una instancia de entidad en otras, ya que Hibernate los vincula a sus padres originales internamente; siempre cree una nueva colección en nuevas instancias (que pueden o no contener los mismos elementos).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!